import React from 'react';

export default function PopupWarp(getModal, platformProps) {
  return class extends React.Component {
    static defaultProps = {
      onVisibleChange(_) {
      },
      okText: 'Ok',
      dismissText: 'Dismiss',
      title: '',
      onOk(_) {
      },
      onDismiss() {
      },
      ...platformProps,
    }

    picker = undefined;

    constructor(props) {
      super(props);
      this.state = {
        pickerValue: 'value' in this.props ? this.props.value : null,
        visible: this.props.visible || false,
      }
    }

    componentWillReceiveProps(nextProps) {
      if ('value' in nextProps) {
        this.setState({
          pickerValue: nextProps.value,
        });
      }
      if ('visible' in nextProps) {
        this.setVisibleState(nextProps.visible);
      }
    }

    fireVisibleChange = (visible) => {
      if (this.state.visible !== visible) {
        if (!('visible' in this.props)) {
          this.setVisibleState(visible);
        }
        this.props.onVisibleChange(visible);
      }
    }

    setVisibleState=(visible)=> {
      this.setState({
        visible,
      });
      if (!visible) {
        this.setState({
          pickerValue: null,
        });
      }
    }

    onPickerChange = (pickerValue) => {
      if (this.state.pickerValue !== pickerValue) {
        this.setState({
          pickerValue: pickerValue,
        });
        const {picker, pickerValueChangeProp} = this.props;
        if (picker && picker.props[pickerValueChangeProp]) {
          picker.props[pickerValueChangeProp](pickerValue);
        }
      }
    }

    saveRef = (picker) => {
      this.picker = picker;
    }

    fireVisibleChange(visible) {
      if (this.state.visible !== visible) {
        if (!('visible' in this.props)) {
          this.setVisibleState(visible);
        }
        this.props.onVisibleChange(visible);
      }
    }


    getRender() {
      const children = this.props.children;
      if (!children) {
        return getModal(this.props, this.state.visible, {
          getContent: this.getContent,
          onOk: this.onOk,
          hide: this.hide,
          onDismiss: this.onDismiss,
        });
      }

      const {WrapComponent, disabled} = this.props;

      const newChildProps = {};
      if (!disabled) {
        newChildProps[this.props.triggerType] = this.onTriggerClick;
      }

      return (
        <WrapComponent style={this.props.wrapStyle}>
          {React.cloneElement(children, newChildProps)}
          {
            getModal(this.props, this.state.visible, {
              getContent: this.getContent,
              onOk: this.onOk,
              hide: this.hide,
              onDismiss: this.onDismiss,
            })
          }
        </WrapComponent>
      );
    }

    onTriggerClick = (e) => {
      const child = this.props.children;
      const childProps = child.props || {};
      if (childProps[this.props.triggerType]) {
        childProps[this.props.triggerType](e);
      }
      this.fireVisibleChange(!this.state.visible);
    }

    onOk = () => {
      this.props.onOk(this.picker && this.picker.getValue());
      this.fireVisibleChange(false);
    }

    getContent = () => {
      if (this.props.picker) {
        let {pickerValue} = this.state;
        if (pickerValue === null) {
          pickerValue = this.props.value;
        }
        return React.cloneElement(this.props.picker, ({
          [this.props.pickerValueProp]: pickerValue,
          [this.props.pickerValueChangeProp]: this.onPickerChange,
          ref: this.saveRef,
        }));
      } else {
        return this.props.content;
      }
    }

    onDismiss = () => {
      this.props.onDismiss();
      this.fireVisibleChange(false);
    }

    hide = () => {
      this.fireVisibleChange(false);
    }

    render() {
      return this.getRender();
    }

  }

}